/******************************************************************************

	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010.

	This file is part of Maxsi Engine.

	Maxsi Engine is free software: you can redistribute it and/or modify it
	under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or (at your
	option) any later version.

	Maxsi engine is distributed in the hope that it will be useful, but WITHOUT
	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
	FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
	for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with Maxsi Engine. If not, see <http://www.gnu.org/licenses/>.

	MaxsiEngine.dll
	A general purpose C++ library for the Maxsi Technology Project.

	MaxsiEngineFile.h
	Libary for import and export of Maxsi Engine Files (.mef).

******************************************************************************/

#ifndef MaxsiEngineFile_h
#define MaxsiEngineFile_h

BeginMaxsiNamespace

#ifndef Maxsi_Disable_Deprecated
// Go ahead and delete this on the next clean/release! This is not used any longer
// as it doesn't follow the Maxsi Programming Guidelines, but mostly because the code
// that used these constants was very, very horrible.
enum MaxsiEngineFileReturnValues
{
	INFO_EXPORT_SUCCESS = 2,				// The data was successfully imported into memory
	INFO_IMPORT_SUCCESS = 1,				// The data was successfully imported into memory
	ERROR_NOT_IMPLEMENTED = 0,				// The requested feature is not implemented yet

	ERROR_COULDNT_OPEN_FILE = -1,			// The specified file cannot be opened for binary reading
	ERROR_IMPORT_INVALID_HEADER = -2,		// The datastream doesn't start with the "ME" + trailing zero sequence
	ERROR_IMPORT_INVALID_VERSION = -3,		// The specified version is not supported
	ERROR_IMPORT_EXPIRED_VERSION = -4,		// The specified version has been supported but isn't anymore

	ERROR_INVALID_CALL_NO_FILENAME = -5,	// The called function requires a valid filename

	ERROR_EXPORT_INVALID_VERSION = -6,		// The specified version is not supported
	ERROR_EXPORT_INVALID_BUFFER_SIZE = -7	// Allocated more or less memory than required
};
#endif

//STRUCTLINK MaxsiVariable
//{
//	size_t		NameSize; // originally unsigned char
//	size_t		DataSize; // originally unsigned int
//	BYTE*		VariableData;
//};

STRUCTLINK MaxsiVariable
{
	uint8_t		NameLength;
	size_t		DataSize;
	MESTR*		Name;
	BYTE*		Data;
};

CLASSLINK MaxsiEngineFileFragment
{
public:
	MaxsiEngineFileFragment		( void );
	~MaxsiEngineFileFragment	( void );

private:
	MESTR*		FileName;
	FileSize_t	FileSize; // originally __int64
	BYTE*		FileContent; // originally char*

public:
	MaxsiEngineFileFragment*	Fragment;
	List						Variables;

public:
	BYTE*	Read(size_t* BufferSize = 0); // orignally char* (__int64)
	MaxsiError		Write(BYTE* Data, BYTE** CallerPos = 0); // originally int (char*, char**)
	MaxsiError		Write(BYTE* Data, size_t DataLen, MESTR* FileName = 0, BYTE** CallerPos = 0);
	MESTR*	GetFileName( void );
	FileSize_t	GetFileSize( void );

};

CLASSLINK MaxsiEngineFile
{
public:
	MaxsiEngineFile( void );
	MaxsiEngineFile( MESTR* FileName );
	~MaxsiEngineFile( void );

public:
	uint32_t		Version;
	uint64_t		NumFiles;
	FileSize_t*		FilePos; // originally unsigned __int64*
	List			Variables;

public:
	MaxsiEngineFileFragment*	Fragment;

public:
	// Importing data from a .MEF formatted file/buffer
	MaxsiError	ImportFile(MESTR* FileName, ProgressFunc_Type ProgressFunc = 0);
	MaxsiError	ImportFile(BYTE* Data, size_t DataLen, ProgressFunc_Type ProgressFunc = 0); // originally int (char*,__int64, ProgressFunc_Type)
	MaxsiError	ImportFile_Version_1(BYTE* Data, size_t DataLen, ProgressFunc_Type ProgressFunc = 0); // originally int (char*,__int64, ProgressFunc_Type)
	MaxsiError	ImportFile_Version_2(BYTE* Data, size_t DataLen, ProgressFunc_Type ProgressFunc = 0); // originally int (char*,__int64, ProgressFunc_Type)

	// Importing data to file/buffer written in the .MEF format
	MaxsiError	ExportFile(MESTR* FileName, ProgressFunc_Type ProgressFunc = 0);
	MaxsiError	ExportFile(BYTE** Data, size_t* DataLen, ProgressFunc_Type ProgressFunc = 0);
	MaxsiError	ExportFile_Version_1(BYTE** Data, size_t* DataLen, ProgressFunc_Type ProgressFunc = 0);
	MaxsiError	ExportFile_Version_2(BYTE** Data, size_t* DataLen, ProgressFunc_Type ProgressFunc = 0);

	// Extract the content(s) to a folder
	MaxsiError	ExtractFile(BYTE** Buffer, size_t* DataLen, MaxsiEngineFileFragment* TheFragment);
	MaxsiError	ExtractFile(MESTR* FileName, MESTR* Directory);
	MaxsiError	ExtractFiles(MESTR* Directory);
	MaxsiError	ExtractFile(MaxsiEngineFileFragment* Fragment, MESTR* Directory);

	// Creates a new fragment and forwards the call
	MaxsiEngineFileFragment*	ReadFile(MESTR* FileName, List* Variables = 0);
	MaxsiEngineFileFragment*	WriteFile(BYTE* Data);
	MaxsiEngineFileFragment*	WriteFile(MESTR* FileName, MESTR* Alias, List Variables = 0);
	MaxsiEngineFileFragment*	WriteFile(MESTR* FileName, BYTE* Data, size_t DataLen, List Variables = 0);
};

LINK	MaxsiVariable*	GetVariable(List list, MESTR* VariableName);
LINK	MaxsiVariable*	SetVariable(List list, MESTR* VariableName, BYTE* Buffer, size_t BufferSize);
LINK	BYTE*			GetVariableData(List list, MESTR* VariableName);
LINK	List			DuplicateVariableList(List list);
LINK	bool			DeleteVariableList(List list);

#ifndef Maxsi_Disable_Deprecated
// Incase anyone is lazy
typedef MaxsiEngineFile MEF;
#endif

/* FORMAT SPECIFICATION as of 14 Jun 2010 (Backwards compatible with the Aug 31 2008 specification)
	// Version 1
	ME File

	UTF8_t[3]							= "ME"	// ME followed by a nulltermination
	uint32_t				version		= 1
	uint32_t				NumFiles
	MEFile[NumFiles]

	MeFile:
	uint8_t					FileNameSize
	UTF8_t[FileNameSize]	FileName
	uint32_t				FileSize
	BYTE[FileSize]			FileContent


	// Version 2
	ME File

	UTF8_t[3]							=	"ME"
	uint32_t				version		=	2
	VariableArray			Variables
	uint32_t				NumFiles
	MEFile[NumFiles]

	MeFile:
	VariableArray			Variables
	uint8_t					FileNameSize
	UTF8_t[FileNameSize]	FileName
	uint32_t				FileSize
	char[FileSize]			FileContent	

	VariableArray:
	uint32_t				NumVariables
	Variable[NumVariables]

	Variable:
	uint8_t					NameSize	// NOTE: All variables with a leading _ is reserved for later usage.
	uint32_t				DataSize
	BYTE[NameSize+DataSize] VariableDatas
*/

/* FORMAT SPECIFICATION as of Aug 31 2008 (Deprecated because it relies on a 32-bit Windows Visual Studio Environment)
	// Version 1
	ME File

	char[3]								= "ME"	// ME followed by a nulltermination
	unsigned int			version		= 1
	unsigned long			NumFiles
	MEFile[NumFiles]

	MeFile:
	unsigned char			FileNameSize
	char[FileNameSize]		FileName
	unsigned long			FileSize
	char[FileSize]			FileContent


	// Version 2
	ME File

	char[3]								=	"ME"
	unsigned int			version		=	2
	VariableArray			Variables
	unsigned long			NumFiles
	MEFile[NumFiles]

	MeFile:
	VariableArray			Variables
	unsigned char			FileNameSize
	char[FileNameSize]		FileName
	unsigned long			FileSize
	char[FileSize]			FileContent	

	VariableArray:
	unsigned int			NumVariables
	Variable[NumVariables]

	Variable:
	unsigned char			NameSize	// NOTE: All variables with a leading _ is reserved for later usage.
	unsigned int			DataSize
	char[NameSize+DataSize] VariableDatas
*/

EndMaxsiNamespace

#endif
